using System;
using System.Text;
using System.Collections.Generic;
using NUnit.Framework;
using Microsoft.Practices.RepositoryFactory.CommonHelpers;

namespace Microsoft.Practices.RepositoryFactory.Tests.CommonHelpers
{
    /// <summary>
    /// Summary description for NameResolverFixture
    /// </summary>
    [TestFixture]
    public class NameResolverFixture
    {
        [Test]
        public void GeneratesRepositoryAssetsFolderName()
        {
            string entityName = "Customer";
            string repositoryFolderName = NameResolver.ResolveFolderName(entityName);

            Assert.AreEqual("CustomerDataAccess", repositoryFolderName);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ResolveFolderNameThrowsArgumentNullExceptionOnNullEntityName()
        {
            NameResolver.ResolveFolderName(null);
        }

        [Test]
        public void GeneratesRepositoryNamespaceForCSharpDataAccessProject()
        {
            string dataAccessNamespace = "CompanyName.SomeBusinessModule.DataAccessObjects";
            string entityName = "Customer";

            string expectedRepositoryNamespace = "CompanyName.SomeBusinessModule.DataAccessObjects.CustomerDataAccess";
            string actualRespositoryNamespace =
                NameResolver.ResolveNamespace(false, dataAccessNamespace, entityName);

            Assert.AreEqual(expectedRepositoryNamespace, actualRespositoryNamespace,
                String.Format("Expected {0} but got {1})", expectedRepositoryNamespace, actualRespositoryNamespace));

            Console.WriteLine(actualRespositoryNamespace);
        }

        [Test]
        public void GeneratesRepositoryNamespaceForVBDataAccessProject()
        {
            string dataAccessNamespace = "CompanyName.SomeBusinessModule.DataAccessObjects";
            string entityName = "Customer";

            string expectedRepositoryNamespace = "CustomerDataAccess";
            string actualRespositoryNamespace =
                NameResolver.ResolveNamespace(true, dataAccessNamespace, entityName);

            Assert.AreEqual(expectedRepositoryNamespace, actualRespositoryNamespace,
                String.Format("Expected {0} but got {1})", expectedRepositoryNamespace, actualRespositoryNamespace));

            Console.WriteLine(actualRespositoryNamespace);
        }

        [Test]
        public void ResolvesEntityNamespaceForVbProjects()
        {
            const string BusinessEntityNamespace = "CompanyName.SomeBusinessModule.BusinessEntities";
            
            Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel.Entity entity = new
                Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel.Entity();
            entity.Namespace = BusinessEntityNamespace;

            String businessEntityDefaultOrRootNamespace = BusinessEntityNamespace;


            StringAssert.AreEqualIgnoringCase(BusinessEntityNamespace, 
                NameResolver.ResolveBusinessEntityNamespace(entity, businessEntityDefaultOrRootNamespace));

        }

        [Test]
        public void ResolvesEntityNamespaceForCsProjects()
        {
            const string BusinessEntityNamespace = "CompanyName.SomeBusinessModule.BusinessEntities";

            Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel.Entity entity = new
                Microsoft.Practices.RepositoryFactory.CodeGeneration.ObjectModel.Entity();
            entity.Namespace = String.Empty;

            String businessEntityDefaultOrRootNamespace = BusinessEntityNamespace;

            StringAssert.AreEqualIgnoringCase(BusinessEntityNamespace,
                NameResolver.ResolveBusinessEntityNamespace(entity, businessEntityDefaultOrRootNamespace));

        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ResolveNamespaceThrowsArgumentNullExceptionOnNullDataAccessNamespace()
        {
            string dataAccessNamespace = null;
            string entityName = "Customer";
            NameResolver.ResolveNamespace(false, dataAccessNamespace, entityName);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ResolveNamespaceThrowsArgumentNullExceptionOnNullEntityName()
        {
            string dataAccessNamespace = "CompanyName.SomeBusinessModule.DataAccessObjects";
            string entityName = null;
            NameResolver.ResolveNamespace(false, dataAccessNamespace, entityName);
        }

        [Test]
        public void ReturnsSqlServerRepositoryDatabaseNamespace()
        {
            string databaseProviderName = "System.Data.SqlClient";
            string expectedRepositoryDatabaseNamespace = "Microsoft.Practices.Repository.SqlServer";

            string actualRepositoryDatabaseNamespace = NameResolver.ResolveRepositoryDatabaseNamespace(databaseProviderName);

            Assert.AreEqual(expectedRepositoryDatabaseNamespace, actualRepositoryDatabaseNamespace);
        }

        [Test]
        public void ReturnsMsOraRepositoryDatabaseNamespace()
        {
            string databaseProviderName = "System.Data.OracleClient";
            string expectedRepositoryDatabaseNamespace = "Microsoft.Practices.Repository.Oracle";

            string actualRepositoryDatabaseNamespace = NameResolver.ResolveRepositoryDatabaseNamespace(databaseProviderName);

            Assert.AreEqual(expectedRepositoryDatabaseNamespace, actualRepositoryDatabaseNamespace);
        }

        [Test]
        public void ReturnsODPRepositoryDatabaseNamespace()
        {
            string databaseProviderName = "Oracle.DataAccess.Client";
            string expectedRepositoryDatabaseNamespace = "Microsoft.Practices.Repository.Oracle";

            string actualRepositoryDatabaseNamespace = NameResolver.ResolveRepositoryDatabaseNamespace(databaseProviderName);

            Assert.AreEqual(expectedRepositoryDatabaseNamespace, actualRepositoryDatabaseNamespace);
        }

        [Test]
        [ExpectedException(typeof(Exception))]
        public void ThrowsDatabaseProviderNotSupportedException()
        {
            string databaseProviderName = "DatabaseProviderNotSupported";

            try
            {
                NameResolver.ResolveRepositoryDatabaseNamespace(databaseProviderName);
            }
            catch (Exception ex)
            {
                Console.Error.Write(ex.Message);
                throw;
            }

        }

    }
}
